package com.leyou.gateway.filter;

import com.leyou.common.auth.entity.Payload;
import com.leyou.common.auth.entity.UserInfo;
import com.leyou.common.auth.utils.JwtUtils;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.gateway.config.FilterProperties;
import com.leyou.gateway.config.JwtProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 权限过滤器
 * 1. 每次请求都进入这个过滤器
 * 2. 如果携带了token放行
 * 3. 没有携带token 拦截并返回401
 */
@Slf4j
@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private FilterProperties filterProperties;


    /**
     * 校验token
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取请求对象
        ServerHttpRequest request = exchange.getRequest();

        //白名单校验
        if(isAllowRequest(request)){
            System.out.println("放行了..........."+request.getURI().getPath());
            // 允许的白名单，直接放行
            return chain.filter(exchange);
        }

        //获取cookie
        HttpCookie cookie = request.getCookies().getFirst(jwtProperties.getUser().getCookieName());
        try {
            //获取cookie中的token
            if (cookie != null){
                String name = cookie.getName();
                String token = cookie.getValue();
                //解析token
                Payload<UserInfo> payload = JwtUtils.getInfoFromToken(token, jwtProperties.getPublicKey(), UserInfo.class);

                //TODO 权限控制(以下代码为token肯定合法的情况下执行)
                //略

            }else{
                log.error("cookie为空");
                throw new LyException(ExceptionEnum.INVALID_USERNAME_PASSWORD);
            }
        } catch (Exception e) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);  //设置异常状态码
            return exchange.getResponse().setComplete();    //终止并马上返回响应
        }
        //放行
        return chain.filter(exchange);
    }

    /**
     * 白名单放行
     * @param request   请求对象用于获取请求路径
     * @return  true: 放行    false: 拦截
     */
    private boolean isAllowRequest(ServerHttpRequest request) {
        //请求路径
        String path = request.getURI().getPath();
        //白名单
        List<String> allowPaths = filterProperties.getAllowPaths();
        for (String allowPath : allowPaths) {
            if(path.startsWith(allowPath)){
                // 可以放行的路径
                return true;
            }
        }
        return false;
    }



    /**
     * 返回值是int, 数值越小越先执行
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
